package de.gof.ppstool.bestellverwaltung;

import static de.gof.ppstool.util.LogUtil.begin;
import static de.gof.ppstool.util.LogUtil.end;
import static de.gof.ppstool.util.LogUtil.logBeginTrans;
import static de.gof.ppstool.util.LogUtil.logCommit;
import static de.gof.ppstool.util.LogUtil.logRollback;
import java.io.Serializable;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import de.gof.ppstool.bestellverwaltung.db.BestellpositionEntity;
import de.gof.ppstool.bestellverwaltung.db.BestellpositionDuplikatException;
import de.gof.ppstool.bestellverwaltung.db.BestellpositionNotFoundException;
import de.gof.ppstool.bestellverwaltung.db.Bestellung;
import de.gof.ppstool.bestellverwaltung.db.BestellungNotFoundException;
import de.gof.ppstool.bestellverwaltung.db.IBestellverwaltungDAO;
import de.gof.ppstool.util.GofUtil;

@Service(IBestellverwaltung.NAME)
public class Bestellverwaltung implements IBestellverwaltung, Serializable {
	/** 
	 */

	private static final long serialVersionUID = -5088579410801412860L;
	private static final Log LOG = LogFactory.getLog(GofUtil.class);
	private static final boolean DEBUG = LOG.isDebugEnabled();
	private static final boolean TRACE = LOG.isDebugEnabled();
	@SuppressWarnings("unused")
	@PersistenceContext
	private EntityManager em;
	@Autowired
	private IBestellverwaltungDAO dao;

	// = GofUtil.getBestellverwaltungDao();
	public Bestellverwaltung() {
		super();
	}

	/**
	 * { @inheritDoc}
	 */
	public BestellpositionEntity aendereBestellpostion(
			BestellpositionEntity bestellposition)
			throws BestellpositionNotFoundException {
		if (bestellposition == null) {
			return null;
		}

		if (TRACE)
			logBeginTrans(LOG);

		bestellposition = dao.aendereBestellpostion(bestellposition);
		if (TRACE)
			logCommit(LOG);

		return bestellposition;
	}

	/**
	 * { @inheritDoc}
	 */
	public Bestellung aendereBestellung(Bestellung bestellung)
			throws BestellungNotFoundException {
		if (bestellung == null) {
			return null;
		}

		if (TRACE)
			logBeginTrans(LOG);

		bestellung = dao.aendereBestellung(bestellung);
		if (TRACE)
			logCommit(LOG);

		return bestellung;
	}

	/**
	 * { @inheritDoc}
	 * @throws BestellungNotFoundException
	 */
	public BestellpositionEntity erstelleBestellposition(
			BestellpositionEntity bestellposition)
			throws BestellpositionDuplikatException,
			BestellungNotFoundException {
		if (DEBUG)
			begin(LOG, bestellposition);

		if (TRACE)
			logBeginTrans(LOG);

		Bestellung bestellung = bestellposition.getBestellung();
		final Long bestellungId = bestellung.getBestellungId();
		try {
			bestellung = dao.findeBestellungNachId(bestellungId);
		} catch (BestellungNotFoundException e) {
			//trans.rollback();  //TODO
			if (TRACE)
				logRollback(LOG);

			if (DEBUG)
				end(LOG, e.getMessage());

			//throw e; TODO
			return bestellposition;
			//FIXME only a test
		}

		final List<BestellpositionEntity> bestellpositionen = bestellung
				.getBestellpositionen();
		// Pruefung bzgl. Duplikat
		if (bestellpositionen != null) {
			for (BestellpositionEntity b : bestellpositionen) {
				if (b == bestellposition)
					// das einzufuegende Bestellungsobjekt
					continue;

				if (!bestellposition.equals(b))
					continue;

				bestellpositionen.remove(bestellposition);
				//trans.rollback();  //TODO
				if (TRACE)
					logRollback(LOG);

				if (DEBUG)
					end(LOG, "error.bestellverwaltung.bestellpositionDuplikat"
							+ bestellposition);

				throw new BestellpositionDuplikatException(bestellungId);
			}
		}

		// Abspeichern des neuen Bestellungsobjektes
		dao.erstelleBestellposition(bestellposition);
		if (TRACE)
			logCommit(LOG);

		if (DEBUG)
			end(LOG, bestellposition);

		return bestellposition;
	}

	/**
	 * { @inheritDoc}
	 */
	public Bestellung erstelleBestellung(Bestellung bestellung) {
		if (DEBUG)
			begin(LOG, bestellung);

		if (TRACE)
			logBeginTrans(LOG);

		try {
			dao.erstelleBestellung(bestellung);
		} catch (Exception e)//TODO
		{
			if (TRACE)
				logRollback(LOG);

			if (DEBUG)
				end(LOG, e.getMessage());

		}

		if (TRACE)
			logCommit(LOG);

		if (DEBUG)
			end(LOG, bestellung);

		return bestellung;
	}

	/**
	 * { @inheritDoc}
	 */
	public void loescheBestellung(Bestellung bestellung)
			throws BestellungNotFoundException {
		if (DEBUG)
			begin(LOG, bestellung);

		if (bestellung == null) {
			if (DEBUG)
				end(LOG, bestellung);

			return;
		}

		if (TRACE)
			logBeginTrans(LOG);

		dao.loescheBestellung(bestellung);
		if (TRACE)
			logCommit(LOG);

		if (DEBUG)
			end(LOG);

	}

	/**
	 * { @inheritDoc}
	 */
	public void loescheBestellposition(BestellpositionEntity bestellpostion)
			throws BestellpositionNotFoundException {
		if (DEBUG)
			begin(LOG, bestellpostion);

		if (bestellpostion == null) {
			if (DEBUG)
				end(LOG, bestellpostion);

			return;
		}

		if (TRACE)
			logBeginTrans(LOG);

		dao.loescheBestellposition(bestellpostion);
		if (TRACE)
			logCommit(LOG);

		if (DEBUG)
			end(LOG);

	}

	/**
	 * { @inheritDoc}
	 */
	public List<BestellpositionEntity> findeAlleBestellpositionen()
			throws BestellpositionNotFoundException {
		if (TRACE)
			logBeginTrans(LOG);

		List<BestellpositionEntity> bestellpositionen = null;
		try {
			bestellpositionen = dao.findeAlleBestellpositionen();
		} catch (BestellpositionNotFoundException e) {
			if (TRACE)
				logRollback(LOG);

			if (DEBUG)
				end(LOG, e.getMessage());

			throw e;
		}

		if (TRACE)
			logCommit(LOG);

		if (DEBUG)
			end(LOG);

		return bestellpositionen;
	}

	/**
	 * { @inheritDoc}
	 */
	public List<Bestellung> findeAlleBestellungen()
			throws BestellungNotFoundException {
		if (TRACE)
			logBeginTrans(LOG);

		List<Bestellung> bestellungen = null;
		try {
			bestellungen = dao.findeAlleBestellungen();
		} catch (BestellungNotFoundException e) {
			if (TRACE)
				logRollback(LOG);

			if (DEBUG)
				end(LOG, e.getMessage());

			throw e;
		}

		if (TRACE)
			logCommit(LOG);

		if (DEBUG)
			end(LOG);

		return bestellungen;
	}

	/**
	 * { @inheritDoc}
	 */
	public BestellpositionEntity findeBestellpositionNachId(
			Long bestellpositionId) throws BestellpositionNotFoundException {
		if (DEBUG)
			begin(LOG, bestellpositionId);

		if (TRACE)
			logBeginTrans(LOG);

		BestellpositionEntity bestellposition = null;
		try {
			bestellposition = dao.findeBestellpositionNachId(bestellpositionId);
		} catch (BestellpositionNotFoundException e) {
			if (TRACE)
				logCommit(LOG);

			if (DEBUG)
				end(LOG, e.getMessage());

			throw e;
		}

		if (TRACE)
			logCommit(LOG);

		if (DEBUG)
			end(LOG, bestellposition);

		return bestellposition;
	}

	/**
	 * { @inheritDoc}
	 */
	public Bestellung findeBestellungNachId(Long bestellungId)
			throws BestellungNotFoundException {
		if (DEBUG)
			begin(LOG, bestellungId);

		Bestellung bestellung = null;
		try {
			bestellung = dao.findeBestellungNachId(bestellungId);
		} catch (BestellungNotFoundException e) {
			if (DEBUG)
				end(LOG, e.getMessage());

			throw e;
		}

		if (TRACE)
			logCommit(LOG);

		if (DEBUG)
			end(LOG, bestellung);

		return bestellung;
	}

}
